/**
 * @author xiao zhou
 * @lastEditTime 2021-06-10 22:20:45
 * @description
 */

const fse = require('fs-extra')
const inquirer = require('inquirer')
const { succeed, error, underline, log } = require('../utils')
const { baseConfig, deployConfigPath } = require('../config')

// 获取用户输入基础信息
const getBaseInputInfo = () => inquirer.prompt(baseConfig)

// 生成环境配置信息
const createdEnvConfig = env => [
  {
    'type': 'input',
    'name': `${env}Name`,
    'message': '环境名称',
    'default': env === 'dev' ? '开发环境' : env === 'test' ? '测试环境' : env === 'prod' ? '生产环境' : '其它'
  },
  {
    'type': 'input',
    'name': `${env}Script`,
    'message': '打包命令',
    'default': `npm run build:${env}`
  },
  {
    'type': 'input',
    'name': `${env}Host`,
    'message': '服务器地址'
  },
  {
    'type': 'number',
    'name': `${env}Port`,
    'message': '服务器端口号',
    'default': 22
  },
  {
    'type': 'input',
    'name': `${env}Username`,
    'message': '服务器登录名',
    'default': 'root'
  },
  {
    'type': 'password',
    'name': `${env}Password`,
    'message': '服务器密码'
  },
  {
    'type': 'input',
    'name': `${env}DistPath`,
    'message': '本地打包目录',
    'default': 'dist'
  },
  {
    'type': 'input',
    'name': `${env}WebDir`,
    'message': '部署路径'
  },
  {
    'type': 'input',
    'name': `${env}BakDir`,
    'message': '备份路径'
  },
  {
    'type': 'confirm',
    'name': `${env}IsRemoveRemoteFile`,
    'message': '是否删除远程文件',
    'default': true
  },
  {
    'type': 'confirm',
    'name': `${env}IsRemoveLocalFile`,
    'message': '是否删除本地打包文件',
    'default': true
  }
]

// 获取用户输入环境信息
const getEnvInputInfo = baseInputInfo => inquirer.prompt(baseInputInfo.deployEnvList.map(env => createdEnvConfig(env)).flat())

// 创建JSON对象
const createJsonObj = userInputInfo => {
  const jsonObj = {
    'projectName': userInputInfo.projectName,
    'privateKey': userInputInfo.privateKey,
    'passphrase': userInputInfo.passphrase,
    'server': {}
  }

  const { deployEnvList } = userInputInfo

  const createObj = env => ({
    'name': userInputInfo[`${env}Name`],
    'script': userInputInfo[`${env}Script`],
    'host': userInputInfo[`${env}Host`],
    'port': userInputInfo[`${env}Port`],
    'username': userInputInfo[`${env}Username`],
    'password': userInputInfo[`${env}Password`],
    'distPath': userInputInfo[`${env}DistPath`],
    'webDir': userInputInfo[`${env}WebDir`],
    'bakDir': userInputInfo[`${env}BakDir`],
    'isRemoveRemoteFile': userInputInfo[`${env}IsRemoveRemoteFile`],
    'isRemoveLocalFile': userInputInfo[`${env}IsRemoveLocalFile`]
  })
  deployEnvList.forEach(env => {
    jsonObj['server'][env] = createObj(env)
  })
  return jsonObj
}

// 添加脚本命令到项目的package.json文件中
const addBashToPackage = userInputInfo => {
  const { deployEnvList } = userInputInfo
  // eslint-disable-next-line no-undef
  const packagePath = `${process.cwd()}/package.json`
  if (fse.pathExistsSync(packagePath)) {
    try {
      const pkgJson = fse.readJsonSync(packagePath)
      if (pkgJson['scripts']) {
        if (!pkgJson['scripts']['deploy']) {
          pkgJson['scripts']['deploy'] = '@xz2xl/auto-deploy deploy'
        }
        deployEnvList.forEach(env => {
          if (!pkgJson['scripts'][`deploy:${env}`]) {
            pkgJson['scripts'][`deploy:${env}`] = `@xz2xl/auto-deploy deploy --mode ${env}`
          }
        })
      }
      fse.writeJsonSync(packagePath, pkgJson, {
        'spaces': 2
      })
    } catch (error) {
      log(error)
      // eslint-disable-next-line no-undef
      process.exit(1)
    }
  } else {
    error('项目根目录不存在 package.json 文件')
    // eslint-disable-next-line no-undef
    process.exit(1)
  }
}

// 创建配置文件
const createConfigFile = jsonObj => {
  const str = `module.exports = ${JSON.stringify(jsonObj, null, 2)}`
  fse.outputFileSync(deployConfigPath, str)
}

module.exports = async () => {
  if (fse.pathExistsSync(deployConfigPath)) {
    error('deploy.config.js 配置文件已存在, 请勿重复初始化！')
    // eslint-disable-next-line no-undef
    process.exit(1)
  } else {
    const baseInputInfo = await getBaseInputInfo()
    const envInputInfo = await getEnvInputInfo(baseInputInfo)
    const userInputInfo = { ...baseInputInfo, ...envInputInfo }
    createConfigFile(createJsonObj(userInputInfo))
    addBashToPackage(userInputInfo)
    succeed(`配置文件生成成功，请查看项目目录下的 ${underline('deploy.config.js')} 文件确认配置是否正确`)
    // eslint-disable-next-line no-undef
    process.exit(0)
  }
}
